package com.yuandian.customer.perception.controller;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.yuandian.api.customer_perception.po.BusinessAnalysisParams;
import com.yuandian.api.customer_perception.po.BusinessComparativeAnalysisParams;
import com.yuandian.api.customer_perception.vo.BusinessOperatorOverviewVo;
import com.yuandian.api.customer_perception.vo.BusinessStepAnalysisVo;
import com.yuandian.api.management.feign.RemoteAreaService;
import com.yuandian.api.management.feign.RemoteBusinessHallService;
import com.yuandian.bpm.common.core.constant.CommonConstants;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.customer.perception.service.IBusinessAnalysisService;
import com.yuandian.utils.YDateUtil;
import com.yuandian.utils.poi.ExcelTitleUtils;
import com.yuandian.utils.poi.ExcelUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 说明：业务分析controller
 * @Author linshihe
 * @Date 2021/8/11 13:33
 */
@Slf4j
@Api(value = "业务分析接口", tags = "业务分析接口")
@RestController
@RequestMapping("/business/analysis")
public class BusinessAnalysisController {


    @Autowired
    private IBusinessAnalysisService businessAnalysisService;

//    @Autowired
//    private ISearchOptionService searchOptionService;

    @Autowired
    private RemoteAreaService remoteAreaService;

    @Autowired
    private RemoteBusinessHallService remoteBusinessHallService;

    /**
     * 查询业务分析概况
     * @param params 系统分析请求参数
     * @return 通用返回对象
     */
	@ApiOperation(value = "业务分析-查询业务分析概况", notes = "业务分析-查询业务分析概况")
	@PostMapping("/queryBusinessAnalysisOverview")
    public R<Object>  queryBusinessAnalysisOverview(@RequestBody BusinessAnalysisParams params) {
        return businessAnalysisService.queryBusinessAnalysisOverview(params);
    }

    /**
     * 查询业务告警占比
     * @param params 请求参数
     * @return 通用返回对象
     */
	@ApiOperation(value = "业务分析-查询业务告警占比", notes = "业务分析-查询业务告警占比")
	@PostMapping("/queryBusinessAlarmProportion")
    public R<Object> queryBusinessAlarmProportion(@RequestBody  BusinessAnalysisParams params) {
        return businessAnalysisService.queryBusinessAlarmProportion(params);
    }

    /**
     * 查询业务指标趋势
     * @param params 请求参数
     * @return 通用返回对象
     */
	@ApiOperation(value = "业务分析-查询业务指标趋势", notes = "业务分析-查询业务指标趋势")
	@PostMapping("/queryBusinessIndicatorTrend")
    public R<Object> queryBusinessIndicatorTrend(@RequestBody  BusinessAnalysisParams params) {
        // 查询 业务健康度、平均办理时长、平均响应时长
        params.setType(1);
        return businessAnalysisService.queryBusinessIndicatorTrend(params);
    }

    /**
     * 查询业务指标趋势
     * 业务访问量、业务受理量、业务失败量、告警量--busi_sys_detail_stat_m-KhgzBusinessDetailStatTask-业务指标趋势-延迟3分钟-//api-khgz/modules/business/analysis/queryBusinessIndicatorWholeTrend
     * @param params 请求参数
     * @return 通用返回对象
     */
	@ApiOperation(value = "业务分析-查询业务指标趋势 业务访问量、业务受理量、业务失败量、告警量", notes = "业务分析-查询业务指标趋势 业务访问量、业务受理量、业务失败量、告警量")
	@PostMapping("/queryBusinessIndicatorWholeTrend")
    public R<Object> queryBusinessIndicatorWholeTrend(@RequestBody  BusinessAnalysisParams params) {
        // 查询 业务访问量、业务受理量、业务失败量、告警量
        params.setType(2);
        return businessAnalysisService.queryBusinessIndicatorTrend(params);
    }

    /**
     * 业务步骤分析列表
     * @param params 请求参数
     * @return 通用返回对象
     */
	@ApiOperation(value = "业务分析-业务步骤分析列表", notes = "业务分析-业务步骤分析列表")
	@PostMapping("/queryBusinessStepAnalysisList")
    public R<Object> queryBusinessStepAnalysisList(@RequestBody BusinessAnalysisParams params) {
        if (StringUtils.isEmpty(params.getBusinessCode())) {
            return R.failed(-1, "请选择具体业务");
        }
        return businessAnalysisService.queryBusinessStepAnalysisList(params);
    }

    /**
     * 业务步骤分析列表下载
     * @param params 请求参数
     * @return 通用返回对象
     */
	@ApiOperation(value = "业务分析-业务步骤分析列表下载", notes = "业务分析-业务步骤分析列表下载")
	@PostMapping("/queryBusinessStepAnalysisListExport")
    public R<Object> queryBusinessStepAnalysisListExport(@RequestBody BusinessAnalysisParams params, HttpServletResponse response) throws IOException, ParseException {
        if (StringUtils.isEmpty(params.getBusinessCode())) {
            return R.failed(-1, "请选择具体业务");
        }
        List<BusinessStepAnalysisVo> resList =  new ArrayList<>();
        try {
            resList = businessAnalysisService.queryBusinessStepAnalysisListExport(params);
        } catch (Exception e) {
            log.error("所选时间表不存在!但表格需要正常导出.");
        }

        String title = "步骤分析列表";
        // 文件名
        String fileName = title + System.currentTimeMillis();

        // 表单大标题
        List<String> titleParams = new ArrayList<>();
        titleParams.add(title);
        titleParams.add(params.getSystemName());
        titleParams.add(params.getBusinessName());
        if (params.getAreaCode() != null && !"".equals(params.getAreaCode())){
            R<String> nameRes = remoteAreaService.queryAreaName(params.getAreaCode());
            if (nameRes.getCode() == CommonConstants.FAIL){
                log.error("远程调用配置系统获取区域名称失败,错误：{}",nameRes.getMsg());
            }
            titleParams.add(nameRes.getData());
        }
        String formTitleName = ExcelTitleUtils.formTitleName(titleParams,params.getStartTime(),params.getEndTime());

        // 表单大标题合并单元格
        List<List<String>> headList = new ArrayList<>();
        List<String> titleList = Arrays.asList("序号","步骤名称", "系统名称", "请求量", "平均处理时长", "处理时长峰值", "处理时长谷值", "平均响应时长", "失败请求量", "告警请求量", "健康度", "成功率");
        titleList.forEach(s -> {
            List<String> childHeadList = new ArrayList<>();
            childHeadList.add(formTitleName);
            childHeadList.add(s);
            headList.add(childHeadList);
        });

        // 数据整理加上百分号和时间单位
        resList.forEach(analysisVo -> {
            analysisVo.setAvgDealTime(analysisVo.getAvgDealTime() == null ? "" : YDateUtil.getMinSecond(getDouble(Double.parseDouble(analysisVo.getAvgDealTime()) / 1000)));
            analysisVo.setAvgResponeTime(analysisVo.getAvgResponeTime() == null ? "" : YDateUtil.getMinSecond(getDouble(Double.parseDouble(analysisVo.getAvgResponeTime()) / 1000)));
            analysisVo.setMaxDealTime(analysisVo.getMaxDealTime() == null ? "" : YDateUtil.getMinSecond(getDouble(Double.parseDouble(analysisVo.getMaxDealTime()) / 1000)));
            analysisVo.setMinDealTime(analysisVo.getMinDealTime() == null ? "" : YDateUtil.getMinSecond(getDouble(Double.parseDouble(analysisVo.getMinDealTime()) / 1000)));

            analysisVo.setSuccessRate(analysisVo.getSuccessRate() == null ? "" : (analysisVo.getSuccessRate() + "%"));
            analysisVo.setFailRate(analysisVo.getFailRate() == null ? "" : (analysisVo.getFailRate() + "%"));
            analysisVo.setHealthRate(analysisVo.getHealthRate() == null ? "" : (analysisVo.getHealthRate() + "%"));
        });
        //回填序号
        int index = 1;
        for (BusinessStepAnalysisVo businessStepAnalysisVo : resList) {
            businessStepAnalysisVo.setId(index++);
        }
        ExcelUtil.writeExcel(BusinessStepAnalysisVo.class, "", "步骤分析列表", resList, headList, response);

        return R.ok();
    }

    /**
     * 分页查询业务操作员总览
     * @param params 系统分析请求参数
     * @return 通用返回对象
     */
	@ApiOperation(value = "业务分析-分页查询业务操作员总览", notes = "业务分析-分页查询业务操作员总览")
	@PostMapping("/queryBusinessOperatorOverview")
    public R<Object> queryBusinessOperatorOverview(@RequestBody  BusinessAnalysisParams params) {
        return businessAnalysisService.queryBusinessOperatorOverview(params);
    }

    /**
     * 业务操作员总览列表下载
     * @param params 请求参数
     * @return 通用返回对象
     */
	@ApiOperation(value = "业务分析-业务操作员总览列表下载", notes = "业务分析-业务操作员总览列表下载")
	@PostMapping("/queryBusinessOperatorOverviewExport")
    public void queryBusinessOperatorOverviewExport(@RequestBody BusinessAnalysisParams params, HttpServletResponse response) throws IOException, ParseException {

        List<BusinessOperatorOverviewVo> resList = new ArrayList<>();
        try {
            resList = businessAnalysisService.queryBusinessOperatorOverviewExport(params);
        } catch (Exception e) {
            log.error("所选时间表不存在!但表格需要正常导出.");
        }

        String title = "操作员总览列表";
        // 表单大标题
        List<String> titleParams = new ArrayList<>();
        titleParams.add(title);
        titleParams.add(params.getSystemName());
        titleParams.add(params.getBusinessName());
        if (params.getAreaCode() != null && !"".equals(params.getAreaCode())){
            R<String> nameRes = remoteAreaService.queryAreaName(params.getAreaCode());
            if (nameRes.getCode() == CommonConstants.FAIL){
                log.error("远程调用配置系统获取区域名称失败,错误：{}",nameRes.getMsg());
            }
            titleParams.add(nameRes.getData());
        }
        if (params.getBusinessHallId() != null && !"".equals(params.getBusinessHallId())){
            R<String> nameRes = remoteBusinessHallService.queryBusinessHallNameById(params.getBusinessHallId());
            if (nameRes.getCode() == CommonConstants.FAIL){
                log.error("远程调用配置系统获取营业厅名称失败,错误：{}",nameRes.getMsg());
            }
            titleParams.add(nameRes.getData());
        }
        String formTitleName = ExcelTitleUtils.formTitleName(titleParams,params.getStartTime(),params.getEndTime());

        // 表单大标题合并单元格
        List<List<String>> headList = new ArrayList<>();
        List<String> titleList = Arrays.asList("序号","操作员ID", "姓名",params.getOfficeName()+"ID",params.getOfficeName()+"名称", "系统名称", "访问量", "受理量", "告警访问量", "失败访问量", "平均办理时长", "成功率");
        titleList.forEach(s -> {
            List<String> childHeadList = new ArrayList<>();
            childHeadList.add(formTitleName);
            childHeadList.add(s);
            headList.add(childHeadList);
        });

        // 数据整理加上百分号和时间单位
        resList.forEach(operatorOverviewVo -> {
            operatorOverviewVo.setAvgVisitTime(operatorOverviewVo.getAvgVisitTime() == null ? "" : YDateUtil.getMinSecond(getDouble(Double.parseDouble(operatorOverviewVo.getAvgVisitTime()) / 1000)));
            operatorOverviewVo.setSuccessRate(operatorOverviewVo.getSuccessRate() == null ? "" : (operatorOverviewVo.getSuccessRate() + "%"));
         });
        //回填序号
        int index = 1;
        for (BusinessOperatorOverviewVo vo : resList) {
            vo.setId(index++);
            if (vo.getBusinessHallId() == null || vo.getBusinessHallId().equals("")) {
                vo.setBusinessHallId("-");
            }
            if (vo.getBusinessHallName() == null || vo.getBusinessHallName().equals("")) {
                if (vo.getBusinessHallId() == "-") {
                    vo.setBusinessHallName("-");
                } else {
                    vo.setBusinessHallName("未知");
                }
            }
            if (vo.getOperatorId() == null || vo.getOperatorId().equals("")) {
                vo.setOperatorId("-");
            }
            if (vo.getOperatorName() == null || vo.getOperatorName().equals("")) {
                if (vo.getOperatorId() == "-") {
                    vo.setOperatorName("-");
                } else {
                    vo.setOperatorName("未知");
                }
            }
        }
        ExcelUtil.writeExcel(BusinessOperatorOverviewVo.class, "", "操作员总览列表", resList, headList, response);
    }



    public static Double getDouble(Double allTime) {
        if (allTime == null) {
            return 0d;
        }
        return new BigDecimal(allTime).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }


    /**
     * 查询操作员业务办理量TOPN
     * @param params 请求参数
     * @return 通用返回对象
     */
	@ApiOperation(value = "业务分析-查询操作员业务办理量TOPN", notes = "业务分析-查询操作员业务办理量TOPN")
	@PostMapping("/queryOperatorCompleteTopN")
    public R<Object> queryOperatorCompleteTopN(@RequestBody  BusinessAnalysisParams params) {
        return businessAnalysisService.queryOperatorCompleteTopN(params);
    }


    /**
     * 查询营业员办理业务告警类型分布
     * @param params 请求参数
     * @return 通用返回对象
     */
	@ApiOperation(value = "业务分析-查询营业员办理业务告警类型分布", notes = "业务分析-查询营业员办理业务告警类型分布")
	@PostMapping("/queryOperatorBusinessAlarm")
    public R<Object> queryOperatorBusinessAlarm(@RequestBody BusinessAnalysisParams params) {
        return businessAnalysisService.queryOperatorBusinessAlarm(params);
    }

    /**
     * 查询性能指标概况列表
     * @param paramsList 业务对比分析请求对象集合
     * @return 通用返回对象
     */
	@ApiOperation(value = "业务分析-查询性能指标概况列表", notes = "业务分析-查询性能指标概况列表")
	@PostMapping("/queryPerformanceIndexSurvey")
    public R<Object> queryPerformanceIndexSurvey(@RequestBody List<BusinessComparativeAnalysisParams> paramsList) {
        return businessAnalysisService.queryPerformanceIndexSurvey(paramsList);
    }
}
